__version__ = "$Release 0.78$" #$Sources #Tabla de simbolos, bosquejo
#Importacion de unidades
import Pascal_Error as error    #Unidad encargada de impresion de errores

#Definicion de clases
#----------------------------------------------
class C_ambito: #Creacion de los ambitos
    def __init__(self,nombre,padre,tipo):   #Contructor
        self.nombre = nombre                #nombre del ambito
        self.padre = padre                  #si tiene un ambito padre
        self.tipo_token = tipo              #Constante para que sea generica la pregunta a cualquier cosa...
        self.ambito = True                  #si es un ambito
        self.elementos = {}                 #todos los elementos que lo componen
        self.parametros = {}                #Todos los parametros de este ambito

    def buscar_elemento(self,id):#retorna una tupla [0:True/False,1:objeto buscado]
        if self.elementos.has_key(id): return (True,self.elementos[id])
        elif self.parametros.has_key(id): return (True,self.parametros[id])
        elif not (self.nombre == "main"): return self.padre.buscar_elemento(id)
        else: return (False,C_elemento("No_Existe","No_Existe","No_Existe","No_Existe","No_Existe"))

    def insertar_elemento(self,item): #crea elementos y los manda al diccionario
        if not(self.buscar_elemento(item.nombre)[0]): self.elementos[item.nombre] = item
        else:
            self.elementos[item.nombre] = item
            error.error1(self.padre,item)

    def insertar_parametro(self,item): #crea elementos y los manda al diccionario
        if not (self.parametros.has_key(item.nombre)):
            self.parametros[item.nombre] = item
            self.parametros[item.nombre].posicion = len(self.parametros)
        else: error.error4(self,item)

class C_elemento:
    def __init__(self,nombre,tipo_token,tipo_dato,valor,dimension,oftype = None):
        self.nombre = nombre
        self.ambito = False
        self.tipo_token = tipo_token
        self.tipo_dato = tipo_dato
        self.valor = valor
        self.dimension = dimension
        self.posicion = 0
        self.oftype = oftype

class C_type:
    def __init__(self,nombre,padre):
        self.nombre = nombre
        self.padre = padre
        self.elementos = {}
        #Constantes basicas
        self.ambito = False
        self.tipo_token = "type"
        self.tipo_dato = "type"

    def insertar_elemento(self,item):
        if not(self.elementos.has_key(item.nombre)): self.elementos[item.nombre] = item
        else: error.error20(self,item)

    def buscar_elemento(self,id):
        if self.elementos.has_key(id): return (True,self.elementos[id])
        else:
            for x in self.elementos:
                if x.tipo_token == "type": buscar_elemento(x)

class C_cargador:
    def __init__ (self,str):
        self.dato = str


#Listas de tipos
Numericos=["float","real","double","single","longint","word","shortint","integer","byte"]
Cadenas=["string","char"]

def Compatibilidad_tipos(a,b,Numericos = Numericos,Cadenas = Cadenas):
    if a == b: return True
    elif (a in Numericos) and (b in Numericos): return True
    elif (a in Cadenas) and (b in Cadenas): return True
    else: return False

def Compatibilidad_operador(tipo_dato,operador): #Pasar en tipo [cadena|numerico|booleano]
    cadena  = ['+','=','<','>','>=','<=','<>']
    numerico = ['+','-','*','/','=','<','>','>=','<=','<>']
    booleano = ['or','and','not','xor','=','<>']
    #locals() genera un diccionario de varibles locales
    if operador in locals()[tipo_dato]: return True
    else: return False

def Precedencia_tipos(a,b,Numericos = Numericos,Cadenas = Cadenas):
    if a == b: return a
    elif (a in Numericos) and (Numericos.index(a) < Numericos.index(b)): return a
    elif (a in Cadenas) and (Cadenas.index(a) < Cadenas.index(b)): return a
    else: return b #Si A esta mas bajo en la lista, enviamos este tipo de dato









